package cn.lg.soar.common.util.data;

import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

/**
 * 数值工具
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public interface NumberUtil {

    BigDecimal BIG_DECIMAL_ZERO = BigDecimal.ZERO;
    BigInteger BIG_INTEGER_ZERO = BigInteger.ZERO;
    BigDecimal BIG_DECIMAL_10 = new BigDecimal("10");
    BigInteger BIG_INTEGER_10 = new BigInteger("10");
    BigDecimal BIG_DECIMAL_100 = new BigDecimal("100");
    BigInteger BIG_INTEGER_100 = new BigInteger("100");
    BigDecimal BIG_DECIMAL_1000 = new BigDecimal("1000");
    BigInteger BIG_INTEGER_1000 = new BigInteger("1000");
    BigDecimal BIG_DECIMAL_10000 = new BigDecimal("10000");
    BigInteger BIG_INTEGER_10000 = new BigInteger("10000");

    BigDecimal BIG_DECIMAL_7 = new BigDecimal("7");
    BigInteger BIG_INTEGER_7 = new BigInteger("7");
    BigDecimal BIG_DECIMAL_30 = new BigDecimal("30");
    BigInteger BIG_INTEGER_30 = new BigInteger("30");
    BigDecimal BIG_DECIMAL_60 = new BigDecimal("60");
    BigInteger BIG_INTEGER_60 = new BigInteger("60");

    /**
     * 比较是否相等（会自动转换类型）
     * @param a
     * @param b
     * @return
     */
    static boolean equals(Number a, Number b) {
        // a 为null的情况
        if (a == null) {
            return b == null;
        }
        // b 为null的情况
        if (b == null) {
            return false;
        }
        // 转字符串比较
        String aStr = a.toString();
        String bStr = b.toString();
        if (aStr.equals(bStr)) {
            return true;
        }
        // 终极大招
        BigDecimal aBigDecimal = new BigDecimal(aStr).stripTrailingZeros();
        BigDecimal bBigDecimal = new BigDecimal(bStr).stripTrailingZeros();
        return aBigDecimal.equals(bBigDecimal);
    }

    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static byte of(Byte value, byte defValue) {
        return value == null ? defValue : value;
    }
    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static short of(Short value, short defValue) {
        return value == null ? defValue : value;
    }
    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static int of(Integer value, int defValue) {
        return value == null ? defValue : value;
    }
    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static long of(Long value, long defValue) {
        return value == null ? defValue : value;
    }
    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static float of(Float value, float defValue) {
        return value == null ? defValue : value;
    }
    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static double of(Double value, double defValue) {
        return value == null ? defValue : value;
    }
    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static BigDecimal of(BigDecimal value, BigDecimal defValue) {
        return value == null ? defValue : value;
    }
    /**
     * 转为有效值（非null）
     * @param value 目标值
     * @param defValue 默认值
     * @return
     */
    static BigInteger of(BigInteger value, BigInteger defValue) {
        return value == null ? defValue : value;
    }

    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(Byte value) {
        return gt(value, 0);
    }
    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(Short value) {
        return gt(value, 0);
    }
    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(Integer value) {
        return gt(value, 0);
    }
    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(Long value) {
        return gt(value, 0);
    }
    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(Float value) {
        return gt(value, 0);
    }
    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(Double value) {
        return gt(value, 0);
    }
    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(BigDecimal value) {
        return gt(value, BIG_DECIMAL_ZERO);
    }
    /**
     * 目标值是否为正数
     * @param value 目标值
     * @return
     */
    static boolean positiveNumber(BigInteger value) {
        return gt(value, BIG_INTEGER_ZERO);
    }

    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(Byte value) {
        return lt(value, 0);
    }
    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(Short value) {
        return lt(value, 0);
    }
    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(Integer value) {
        return lt(value, 0);
    }
    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(Long value) {
        return lt(value, 0);
    }
    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(Float value) {
        return lt(value, 0);
    }
    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(Double value) {
        return lt(value, 0);
    }
    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(BigDecimal value) {
        return lt(value, BIG_DECIMAL_ZERO);
    }
    /**
     * 目标值是否为负数
     * @param value 目标值
     * @return
     */
    static boolean negativeNumber(BigInteger value) {
        return lt(value, BIG_INTEGER_ZERO);
    }

    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(Byte value, int contrast) {
        return value != null && value > contrast;
    }
    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(Short value, int contrast) {
        return value != null && value > contrast;
    }
    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(Integer value, int contrast) {
        return value != null && value > contrast;
    }
    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(Long value, long contrast) {
        return value != null && value > contrast;
    }
    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(Float value, float contrast) {
        return value != null && value > contrast;
    }
    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(Double value, double contrast) {
        return value != null && value > contrast;
    }
    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(BigDecimal value, BigDecimal contrast) {
        return value != null && value.compareTo(contrast) > 0;
    }
    /**
     * 大于（目标值 > 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean gt(BigInteger value, BigInteger contrast) {
        return value != null && value.compareTo(contrast) > 0;
    }

    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(Byte value, int contrast) {
        return value != null && value >= contrast;
    }
    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(Short value, int contrast) {
        return value != null && value >= contrast;
    }
    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(Integer value, int contrast) {
        return value != null && value >= contrast;
    }
    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(Long value, long contrast) {
        return value != null && value >= contrast;
    }
    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(Float value, float contrast) {
        return value != null && value >= contrast;
    }
    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(Double value, double contrast) {
        return value != null && value >= contrast;
    }
    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(BigDecimal value, BigDecimal contrast) {
        return value != null && value.compareTo(contrast) >= 0;
    }
    /**
     * 大于等于（目标值 >= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean ge(BigInteger value, BigInteger contrast) {
        return value != null && value.compareTo(contrast) >= 0;
    }

    /**
     * 小于等于（目标值 <= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean le(Byte value, int contrast) {
        return value != null && value <= contrast;
    }
    /**
     * 小于等于（目标值 <= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean le(Short value, int contrast) {
        return value != null && value <= contrast;
    }
    /**
     * 小于等于（目标值 <= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean le(Integer value, int contrast) {
        return value != null && value <= contrast;
    }
    static boolean le(Long value, long contrast) {
        return value != null && value <= contrast;
    }
    /**
     * 小于等于（目标值 <= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean le(Float value, float contrast) {
        return value != null && value <= contrast;
    }
    /**
     * 小于等于（目标值 <= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean le(Double value, double contrast) {
        return value != null && value <= contrast;
    }
    /**
     * 小于等于（目标值 <= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean le(BigDecimal value, BigDecimal contrast) {
        return value != null && value.compareTo(contrast) <= 0;
    }
    /**
     * 小于等于（目标值 <= 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean le(BigInteger value, BigInteger contrast) {
        return value != null && value.compareTo(contrast) <= 0;
    }

    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(Byte value, int contrast) {
        return value != null && value < contrast;
    }
    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(Short value, int contrast) {
        return value != null && value < contrast;
    }
    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(Integer value, int contrast) {
        return value != null && value < contrast;
    }
    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(Long value, long contrast) {
        return value != null && value < contrast;
    }
    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(Float value, float contrast) {
        return value != null && value < contrast;
    }
    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(Double value, double contrast) {
        return value != null && value < contrast;
    }
    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(BigDecimal value, BigDecimal contrast) {
        return value != null && value.compareTo(contrast) < 0;
    }
    /**
     * 小于（目标值 < 对比值）
     * @param value 目标值
     * @param contrast 对比值
     * @return
     */
    static boolean lt(BigInteger value, BigInteger contrast) {
        return value != null && value.compareTo(contrast) < 0;
    }

    /**
     * 加法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal add(BigDecimal a, BigDecimal b) {
        if (a == null) {
            a = BigDecimal.ZERO;
        }
        if (b == null) {
            return a;
        }
        return a.add(b);
    }

    /**
     * 加法（性能好）
     * @param a
     * @param b
     * @return
     */
    static double add(Double a, Double b) {
        if (a == null) {
            a = 0D;
        }
        if (b == null) {
            return a;
        }
        return a + b;
    }

    /**
     * 加法（性能好）
     * @param a
     * @param b
     * @return
     */
    static float add(Float a, Float b) {
        if (a == null) {
            a = 0F;
        }
        if (b == null) {
            return a;
        }
        return a + b;
    }

    /**
     * 加法（性能好）
     * @param a
     * @param b
     * @return
     */
    static int add(Integer a, Integer b) {
        if (a == null) {
            a = 0;
        }
        if (b == null) {
            return a;
        }
        return a + b;
    }

    /**
     * 加法（性能好）
     * @param a
     * @param b
     * @return
     */
    static long add(Long a, Long b) {
        if (a == null) {
            a = 0L;
        }
        if (b == null) {
            return a;
        }
        return a + b;
    }

    /**
     * 加法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal add(Number a, Number b) {
        if (a == null) {
            a = BigDecimal.ZERO;
        }
        if (b == null) {
            return toBigDecimal(a);
        }
        return toBigDecimal(a).add(toBigDecimal(b));
    }

    /**
     * 加法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal add(BigDecimal ...values) {
        if (values.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal result = BigDecimal.ZERO;
        for (BigDecimal value : values) {
            if (value != null) {
                result = result.add(value);
            }
        }
        return result;
    }

    /**
     * 加法（支持多个）
     * @param values
     * @return
     */
    static double add(Double ...values) {
        if (values.length == 0) {
            return 0;
        }
        double result = 0;
        for (Double value : values) {
            if (value != null) {
                result += value;
            }
        }
        return result;
    }

    /**
     * 加法（支持多个）
     * @param values
     * @return
     */
    static float add(Float ...values) {
        if (values.length == 0) {
            return 0;
        }
        float result = 0;
        for (Float value : values) {
            if (value != null) {
                result += value;
            }
        }
        return result;
    }

    /**
     * 加法（支持多个）
     * @param values
     * @return
     */
    static int add(Integer ...values) {
        if (values.length == 0) {
            return 0;
        }
        int result = 0;
        for (Integer value : values) {
            if (value != null) {
                result += value;
            }
        }
        return result;
    }

    /**
     * 加法（支持多个）
     * @param values
     * @return
     */
    static long add(Long ...values) {
        if (values.length == 0) {
            return 0;
        }
        long result = 0;
        for (Long value : values) {
            if (value != null) {
                result += value;
            }
        }
        return result;
    }

    /**
     * 加法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal add(Number ...values) {
        if (values.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal result = BigDecimal.ZERO;
        for (Number value : values) {
            if (value != null) {
                result = result.add(toBigDecimal(value));
            }
        }
        return result;
    }

    /** =======减法=================================================================================================== */

    /**
     * 减法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal sub(BigDecimal a, BigDecimal b) {
        if (a == null) {
            a = BigDecimal.ZERO;
        }
        if (b == null) {
            return a;
        }
        return a.subtract(b);
    }

    /**
     * 减法（性能好）
     * @param a
     * @param b
     * @return
     */
    static double sub(Double a, Double b) {
        if (a == null) {
            a = 0D;
        }
        if (b == null) {
            return a;
        }
        return a - b;
    }

    /**
     * 减法（性能好）
     * @param a
     * @param b
     * @return
     */
    static float sub(Float a, Float b) {
        if (a == null) {
            a = 0F;
        }
        if (b == null) {
            return a;
        }
        return a - b;
    }

    /**
     * 减法（性能好）
     * @param a
     * @param b
     * @return
     */
    static int sub(Integer a, Integer b) {
        if (a == null) {
            a = 0;
        }
        if (b == null) {
            return a;
        }
        return a - b;
    }

    /**
     * 减法（性能好）
     * @param a
     * @param b
     * @return
     */
    static long sub(Long a, Long b) {
        if (a == null) {
            a = 0L;
        }
        if (b == null) {
            return a;
        }
        return a - b;
    }

    /**
     * 减法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal sub(Number a, Number b) {
        if (a == null) {
            a = BigDecimal.ZERO;
        }
        if (b == null) {
            return toBigDecimal(a);
        }
        return toBigDecimal(a).subtract(toBigDecimal(b));
    }

    /**
     * 减法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal sub(BigDecimal ...values) {
        if (values.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal result = values[0];
        if (result == null) {
            return null;
        }
        for (int i = 1; i < values.length; i++) {
            BigDecimal value = values[i];
            if (value != null) {
                result = result.subtract(value);
            }
        }
        return result;
    }

    /**
     * 减法（支持多个）
     * @param values
     * @return
     */
    static double sub(Double ...values) {
        if (values.length == 0) {
            return 0;
        }
        Double result = values[0];
        if (result == null) {
            return 0;
        }
        for (int i = 1; i < values.length; i++) {
            Double value = values[i];
            if (value != null) {
                result -= value;
            }
        }
        return result;
    }

    /**
     * 减法（支持多个）
     * @param values
     * @return
     */
    static float sub(Float ...values) {
        if (values.length == 0) {
            return 0;
        }
        Float result = values[0];
        if (result == null) {
            return 0;
        }
        for (int i = 1; i < values.length; i++) {
            Float value = values[i];
            if (value != null) {
                result -= value;
            }
        }
        return result;
    }

    /**
     * 减法（支持多个）
     * @param values
     * @return
     */
    static int sub(Integer ...values) {
        if (values.length == 0) {
            return 0;
        }
        Integer result = values[0];
        if (result == null) {
            return 0;
        }
        for (int i = 1; i < values.length; i++) {
            Integer value = values[i];
            if (value != null) {
                result -= value;
            }
        }
        return result;
    }

    /**
     * 减法（支持多个）
     * @param values
     * @return
     */
    static long sub(Long ...values) {
        if (values.length == 0) {
            return 0;
        }
        Long result = values[0];
        if (result == null) {
            return 0;
        }
        for (int i = 1; i < values.length; i++) {
            Long value = values[i];
            if (value != null) {
                result -= value;
            }
        }
        return result;
    }

    /**
     * 减法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal sub(Number ...values) {
        if (values.length == 0) {
            return BigDecimal.ZERO;
        }
        if (values[0] == null) {
            return BigDecimal.ZERO;
        }
        BigDecimal result = toBigDecimal(values[0]);
        for (int i = 1; i < values.length; i++) {
            Number value = values[i];
            if (value != null) {
                result = result.subtract(toBigDecimal(value));
            }
        }
        return result;
    }

    /** =======乘法=================================================================================================== */

    /**
     * 乘法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal mul(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) {
            return null;
        }
        return a.multiply(b);
    }

    /**
     * 乘法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Double mul(Double a, Double b) {
        if (a == null || b == null) {
            return null;
        }
        return a * b;
    }

    /**
     * 乘法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Float mul(Float a, Float b) {
        if (a == null || b == null) {
            return null;
        }
        return a * b;
    }

    /**
     * 乘法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Integer mul(Integer a, Integer b) {
        if (a == null || b == null) {
            return null;
        }
        return a * b;
    }

    /**
     * 乘法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Long mul(Long a, Long b) {
        if (a == null || b == null) {
            return null;
        }
        return a * b;
    }

    /**
     * 乘法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal mul(Number a, Number b) {
        if (a == null || b == null) {
            return null;
        }
        return toBigDecimal(a).multiply(toBigDecimal(b));
    }

    /**
     * 乘法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal mul(BigDecimal ...values) {
        if (values.length == 0) {
            return null;
        }
        BigDecimal result =BigDecimal.ONE;
        for (BigDecimal value : values) {
            if (value == null) {
                return null;
            }
            result = result.multiply(value);
        }
        return result;
    }

    /**
     * 乘法（支持多个）
     * @param values
     * @return
     */
    static Double mul(Double ...values) {
        if (values.length == 0) {
            return null;
        }
        double result = 1D;
        for (Double value : values) {
            if (value == null) {
                return null;
            }
            result *= value;
        }
        return result;
    }

    /**
     * 乘法（支持多个）
     * @param values
     * @return
     */
    static Float mul(Float ...values) {
        if (values.length == 0) {
            return null;
        }
        float result = 1F;
        for (Float value : values) {
            if (value == null) {
                return null;
            }
            result *= value;
        }
        return result;
    }

    /**
     * 乘法（支持多个）
     * @param values
     * @return
     */
    static Integer mul(Integer ...values) {
        if (values.length == 0) {
            return null;
        }
        int result = 1;
        for (Integer value : values) {
            if (value == null) {
                return null;
            }
            result *= value;
        }
        return result;
    }

    /**
     * 乘法（支持多个）
     * @param values
     * @return
     */
    static Long mul(Long ...values) {
        if (values.length == 0) {
            return null;
        }
        long result = 1L;
        for (Long value : values) {
            if (value == null) {
                return null;
            }
            result *= value;
        }
        return result;
    }

    /**
     * 乘法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal mul(Number ...values) {
        if (values.length == 0) {
            return null;
        }
        BigDecimal result = BigDecimal.ONE;
        for (Number value : values) {
            if (value == null) {
                return null;
            }
            result = result.multiply(toBigDecimal(value));
        }
        return result;
    }

    /** =======除法=================================================================================================== */

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal div(BigDecimal a, BigDecimal b, int scale, RoundingMode mode) {
        if (a == null || b == null) {
            return null;
        }
        return a.divide(b, scale, mode);
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @param scale
     * @return
     */
    static BigDecimal div(BigDecimal a, BigDecimal b, int scale) {
        if (a == null || b == null) {
            return null;
        }
        return a.divide(b, scale, RoundingMode.HALF_UP);
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @param mode
     * @return
     */
    static BigDecimal div(BigDecimal a, BigDecimal b, RoundingMode mode) {
        if (a == null || b == null) {
            return null;
        }
        return a.divide(b, Math.max(a.scale(), b.scale()), mode);
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal div(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) {
            return null;
        }
        return a.divide(b, Math.max(a.scale(), b.scale()), RoundingMode.HALF_UP);
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Double div(Double a, Double b) {
        if (a == null || b == null) {
            return null;
        }
        return a / b;
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Float div(Float a, Float b) {
        if (a == null || b == null) {
            return null;
        }
        return a / b;
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Integer div(Integer a, Integer b) {
        if (a == null || b == null) {
            return null;
        }
        return a / b;
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static Long div(Long a, Long b) {
        if (a == null || b == null) {
            return null;
        }
        return a / b;
    }

    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal div(Number a, Number b, int scale, RoundingMode mode) {
        if (a == null || b == null) {
            return null;
        }
        return toBigDecimal(a).divide(toBigDecimal(b), scale, mode);
    }
    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal div(Number a, Number b, int scale) {
        if (a == null || b == null) {
            return null;
        }
        return toBigDecimal(a).divide(toBigDecimal(b), scale, RoundingMode.HALF_UP);
    }
    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal div(Number a, Number b, RoundingMode mode) {
        if (a == null || b == null) {
            return null;
        }
        BigDecimal ba = toBigDecimal(a);
        BigDecimal bb = toBigDecimal(b);
        return ba.divide(bb, Math.max(ba.scale(), bb.scale()), mode);
    }
    /**
     * 除法（性能好）
     * @param a
     * @param b
     * @return
     */
    static BigDecimal div(Number a, Number b) {
        if (a == null || b == null) {
            return null;
        }
        BigDecimal ba = toBigDecimal(a);
        BigDecimal bb = toBigDecimal(b);
        return ba.divide(bb, Math.max(ba.scale(), bb.scale()), RoundingMode.HALF_UP);
    }

    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(int scale, RoundingMode mode, BigDecimal ...values) {
        if (values.length == 0) {
            return null;
        }
        BigDecimal result = values[0];
        if (result == null) {
            return null;
        }
        for (int i = 1; i < values.length; i++) {
            BigDecimal value = values[i];
            if (value == null) {
                return null;
            }
            result = result.divide(value, scale, mode);
        }
        return result;
    }

    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(RoundingMode mode, BigDecimal ...values) {
        return div(4, mode, values);
    }
    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(int scale, BigDecimal ...values) {
        return div(scale, RoundingMode.HALF_UP, values);
    }
    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(BigDecimal ...values) {
        return div(4, RoundingMode.HALF_UP, values);
    }

    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static Double div(Double ...values) {
        if (values.length == 0) {
            return null;
        }
        Double result = values[0];
        if (result == null) {
            return null;
        }
        for (int i = 1; i < values.length; i++) {
            Double value = values[i];
            if (value == null) {
                return null;
            }
            result = result / value;
        }
        return result;
    }

    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static Float div(Float ...values) {
        if (values.length == 0) {
            return null;
        }
        Float result = values[0];
        if (result == null) {
            return null;
        }
        for (int i = 1; i < values.length; i++) {
            Float value = values[i];
            if (value == null) {
                return null;
            }
            result = result / value;
        }
        return result;
    }

    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static Integer div(Integer ...values) {
        if (values.length == 0) {
            return null;
        }
        Integer result = values[0];
        if (result == null) {
            return null;
        }
        for (int i = 1; i < values.length; i++) {
            Integer value = values[i];
            if (value == null) {
                return null;
            }
            result = result / value;
        }
        return result;
    }

    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static Long div(Long ...values) {
        if (values.length == 0) {
            return null;
        }
        Long result = values[0];
        if (result == null) {
            return null;
        }
        for (int i = 1; i < values.length; i++) {
            Long value = values[i];
            if (value == null) {
                return null;
            }
            result = result / value;
        }
        return result;
    }

    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(int scale, RoundingMode mode, Number ...values) {
        if (values.length == 0) {
            return null;
        }
        if (values[0] == null) {
            return null;
        }
        BigDecimal result = toBigDecimal(values[0]);
        for (int i = 1; i < values.length; i++) {
            Number value = values[i];
            if (value == null) {
                return null;
            }
            result = result.divide(toBigDecimal(value), scale, mode);
        }
        return result;
    }
    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(int scale, Number ...values) {
        return div(scale, RoundingMode.HALF_UP, values);
    }
    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(RoundingMode mode, Number ...values) {
        return div(4, mode, values);
    }
    /**
     * 除法（支持多个）
     * @param values
     * @return
     */
    static BigDecimal div(Number ...values) {
        return div(4, RoundingMode.HALF_UP, values);
    }

    /** =======四舍五入=================================================================================================== */
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static BigDecimal round(BigDecimal value) {
        return value == null ? null : value.setScale(0, RoundingMode.HALF_UP);
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static BigDecimal round(BigDecimal value, int scale) {
        return value == null ? null : value.setScale(scale, RoundingMode.HALF_UP);
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static BigDecimal round(BigDecimal value, int scale, RoundingMode roundingMode) {
        return value == null ? null : value.setScale(scale, roundingMode);
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static Float round(Float value) {
        return value == null ? null : BigDecimal.valueOf(value).setScale(0, RoundingMode.HALF_UP).floatValue();
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static Float round(Float value, int scale) {
        return value == null ? null : BigDecimal.valueOf(value).setScale(scale, RoundingMode.HALF_UP).floatValue();
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static Float round(Float value, int scale, RoundingMode roundingMode) {
        return value == null ? null : BigDecimal.valueOf(value).setScale(scale, roundingMode).floatValue();
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static Double round(Double value) {
        return value == null ? null : BigDecimal.valueOf(value).setScale(0, RoundingMode.HALF_UP).doubleValue();
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static Double round(Double value, int scale) {
        return value == null ? null : BigDecimal.valueOf(value).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }
    /**
     * 四舍五入
     * @param value
     * @return
     */
    static Double round(Double value, int scale, RoundingMode roundingMode) {
        return value == null ? null : BigDecimal.valueOf(value).setScale(scale, roundingMode).doubleValue();
    }

    /**
     * 转 BigDecimal
     * @param number
     * @return
     */
    static BigDecimal toBigDecimal(String number) {
        if (StringUtils.hasText(number)) {
            return new BigDecimal(number);
        }
        return null;
    }

    /**
     * 转 BigDecimal
     * @param number
     * @return
     */
    static BigDecimal toBigDecimal(Number number) {
        if (number instanceof BigDecimal) {
            return (BigDecimal) number;
        }
        return new BigDecimal(number.toString());
    }

}
